﻿#region Header

/*
    This file is part of ndoctor-statistics.

    ndoctor-statistics is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ndoctor-statistics is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ndoctor-statistics.  If not, see <http://www.gnu.org/licenses/>.
*/

#endregion Header

namespace Probel.NDoctor.Statistics.Components
{
    using System.Collections.Generic;
    using System.Linq;

    using Probel.NDoctor.Statistics.Domain;

    internal class CollectionQuery : Query, ICollectionQuery
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="CollectionQuery"/> class.
        /// </summary>
        /// <param name="repository">The repository.</param>
        public CollectionQuery(IRepository repository)
            : base(repository)
        {
        }

        #endregion Constructors

        #region Methods

        /// <summary>
        /// Gets all users stored in the database.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Application> GetAllApplications()
        {
            return this.Repository.Applications.ToList();
        }

        /// <summary>
        /// Gets the list of all statistics.
        /// </summary>
        /// <returns>
        /// A list with all the statistics
        /// </returns>
        public IEnumerable<StatisticEntry> GetAllStatistics()
        {
            return this.Repository.Statistics.ToList();
        }

        /// <summary>
        /// Gets the average execution time by method. Provides more information than the <see cref="GetAvgExecutionTimeGraph"/>
        /// </summary>
        /// <returns>
        /// A list with all the information about execution time by method
        /// </returns>
        public IEnumerable<Bottleneck> GetBottlenecksArray()
        {
            var list = (from a in this.Repository.Statistics
                        group a by new { a.MethodName, a.TargetTypeName } into grp
                        select new Bottleneck()
                        {
                            AvgExecutionTime = grp.Average(e => e.ExecutionTime) / 1000,
                            AvgThreshold = grp.Average(e => e.Threshold) / 1000,
                            BottleneckCount = (from g in grp where g.IsPossibleBottleneck select g).Count(),
                            CallCount = grp.Count(),
                            MethodName = grp.Key.MethodName,
                            TargetTypeName = grp.Key.TargetTypeName,
                        });

            list = (from item in list
                    where item.BottleneckCount > 0
                    select item);

            return list
                .OrderByDescending(e => e.BottleneckCount)
                .ToList();
        }

        private int GetMethodCount(string targetTypeName, string methodName)
        {
            return (from s in this.Repository.Statistics
                    where s.MethodName == methodName
                       && s.TargetTypeName == targetTypeName
                    select s).Count();
        }

        #endregion Methods
    }
}